#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include "camera_capture.h"
#include <QThread>
#include <windows.h>
#include <Lmcons.h>
#include <QAction>
#include "video_capture.h"
#include "video_capturer_test.h"
#include <iostream>
#include "easylog.h"

const char kCandidateSdpMidName[] = "sdpMid";
const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
const char kCandidateSdpName[] = "candidate";


typedef  struct {
    std::string id;
    std::string name;
    std::vector<webrtc::VideoCaptureCapability> caps;
} VideoDevice;

std::vector<VideoDevice> EnumCaptures()
{
    std::vector<VideoDevice>  ret;
    std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(
      webrtc::VideoCaptureFactory::CreateDeviceInfo());

    int num_devices = info->NumberOfDevices();
    if (!info) {
        RTC_LOG(LERROR) << "CreateDeviceInfo failed";
        return ret;
    }
    for (int i = 0; i < num_devices; ++i) {
        VideoDevice v;
        char name[128];
        char id[128];

        info->GetDeviceName(i,name,128,id,128,nullptr,0);
        int cap_len = info->NumberOfCapabilities(id);
        for(int j = 0;j < cap_len;j++){
            webrtc::VideoCaptureCapability p;
            info->GetCapability(id,j,p);
            qDebug()<<QString::asprintf("获取设备能力cap %d:   "
                                        " %s %d %d %d %d",j,id,
                                        p.width,p.height,p.videoType,p.interlaced);
            v.caps.push_back(p);
        }
        qDebug()<<"device name is "<<name;
        v.name = std::string(name);
        v.id = id;

        //使用索引i创建capture对象
        ret.push_back(v);
    }
    return ret;
}



QString IceGatheringStateName(webrtc::PeerConnectionInterface::IceGatheringState w){
    switch (w) {
    case webrtc::PeerConnectionInterface::IceGatheringState::kIceGatheringNew:
        return "kIceGatheringNew";
    case webrtc::PeerConnectionInterface::IceGatheringState::kIceGatheringGathering:
        return "kIceGatheringGathering";
    case webrtc::PeerConnectionInterface::IceGatheringState::kIceGatheringComplete:
        return "kIceGatheringComplete";
    }

}

QString IceConnectionStateName(webrtc::PeerConnectionInterface::IceConnectionState w){
    switch(w){
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionNew:
        return "kIceConnectionNew";
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionChecking:
        return "kIceConnectionChecking";
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionConnected:
        return "kIceConnectionConnected";
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionCompleted:
        return "kIceConnectionCompleted";
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionFailed:
        return "kIceConnectionFailed";
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionDisconnected:
        return "kIceConnectionDisconnected";
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionClosed:
        return "kIceConnectionClosed";
    case webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionMax:
        return "kIceConnectionMax";
    }
}


MainWindow::MainWindow(QWidget *parent)
    : QssMainWindow(parent)
    , ui(new Ui::MainWindow)
    ,mHandler(new rtc::RefCountedObject<WebrtcHanlder>())
    ,mSignalClient(nullptr)
    ,mModel(nullptr)
    ,mCalling(false)
    ,mRemoteVideoTrack(nullptr)
    ,mLocalVideoTrack(nullptr)
{
    ui->setupUi(this);
    std::vector<VideoDevice> devices = EnumCaptures();

    for(auto itr = devices.begin();itr != devices.end();itr++){
        ui->comboBox->addItem(QString::fromStdString(itr->name),QString::fromStdString(itr->name));
    }

    ui->openGLWidget->show();

    TCHAR username[UNLEN + 1];
    DWORD size = UNLEN + 1;
    GetUserName((TCHAR*)username, &size);
    this->mPeerName = QString::fromWCharArray(username);
    mModel = new QStandardItemModel(this);
    ui->treeView->setModel(mModel);
    connect(ui->treeView,SIGNAL(doubleClicked(QModelIndex)),
            this,SLOT(itemClicked(QModelIndex)));
    connect((WebrtcHanlder*)(mHandler.get()),SIGNAL(OnOfferSdp(QString)),
            this,SLOT(on_local_sdp(QString)));
    connect((WebrtcHanlder*)(mHandler.get()),SIGNAL(OnRemoteTrack(webrtc::MediaStreamTrackInterface*)),
            this,SLOT(on_track_add(webrtc::MediaStreamTrackInterface*)));

    mHandler->InitWebrtc();

}

MainWindow::~MainWindow()
{
    delete ui;
}


const char kAudioLabel[] = "audio_label";
const char kVideoLabel[] = "video_label";
const char kStreamId[] = "stream_id";

void WebrtcHanlder::SetRemotePeerName(QString remote)
{
    this->mRemoteName = remote;
}

WebrtcHanlder::WebrtcHanlder()
{
    mVideoTrack = nullptr;
    mAudioTrack = nullptr;
    m_peer_connection_factory_ = nullptr;
}

int WebrtcHanlder::InitWebrtc()
{
    m_peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
    nullptr /* network_thread */, nullptr /* worker_thread */,
    nullptr /* signaling_thread */, nullptr /* default_adm */,
    webrtc::CreateBuiltinAudioEncoderFactory(),
    webrtc::CreateBuiltinAudioDecoderFactory(),
    webrtc::CreateBuiltinVideoEncoderFactory(),
    webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
    nullptr /* audio_processing */);

    if (!m_peer_connection_factory_) {
    auto x = new QMessageBox(nullptr);
        x->setText("创建peerconnection factory失败");
        x->show();
        exit(0);
    }

    webrtc::PeerConnectionInterface::RTCConfiguration config;
    config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
    config.enable_dtls_srtp = false;
    webrtc::PeerConnectionInterface::IceServer server;
    server.uri = "stun:stun.l.google.com:19302";  // stun服务器
    config.servers.push_back(server);

    if(m_peer_connection_ != nullptr){
        m_peer_connection_.release();
    }
    m_peer_connection_ = m_peer_connection_factory_->CreatePeerConnection(
    config, nullptr, nullptr, this);

    if (!m_peer_connection_) {
        auto x = new QMessageBox(nullptr);
        x->setText("创建peerconnection失败");
        x->show();
        exit(0);
    }
    AddLocalTrack();
}


void WebrtcHanlder::SetSignalClient(SignalClient * cli)
{
    this->mClient = cli;
}

void WebrtcHanlder::CreateOffer()
{
    qDebug()<<"CreateOffer";
    if(nullptr != m_peer_connection_){
        m_peer_connection_->CreateOffer(this,
            webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
    }
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " CreateOffer").toStdString());
}

class DummySetSessionDescriptionObserver
    : public webrtc::SetSessionDescriptionObserver {
public:
    static DummySetSessionDescriptionObserver* Create() {
        return new rtc::RefCountedObject<DummySetSessionDescriptionObserver>();
    }
    virtual void OnSuccess() { RTC_LOG(INFO) << __FUNCTION__; }
    virtual void OnFailure(webrtc::RTCError error) {
        RTC_LOG(INFO) << __FUNCTION__ << " " << ToString(error.type()) << ": "
            << error.message();
    }
};

void WebrtcHanlder::SetRemoteSdp(QString sdp)
{
    qDebug()<<"SetRemoteSdp " << sdp;
    auto doc  = QJsonDocument::fromJson(sdp.toUtf8());
    auto obj = doc.object();
    auto ssdp = obj["sdp"].toString();
    auto type = obj["type"].toString();
    webrtc::SdpType ktype;
    webrtc::SdpParseError error;
    if(type == "answer"){
        ktype = webrtc::SdpType::kAnswer;
    }
    if(type == "offer"){
        ktype = webrtc::SdpType::kOffer;
    }
    std::unique_ptr<webrtc::SessionDescriptionInterface> session_description =
        webrtc::CreateSessionDescription(ktype, ssdp.toStdString(), &error);

    if (!session_description) {
        RTC_LOG(WARNING) << "Can't parse received session description message. "
                        << "SdpParseError was: " << error.description;
        return;
    }
    if(nullptr != m_peer_connection_){
        m_peer_connection_->SetRemoteDescription(
                    DummySetSessionDescriptionObserver::Create(),
                    session_description.release());;
    }
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " SetRemoteSdp " + type + ": " +
                 ssdp).toStdString());
}


void WebrtcHanlder::SetRemoteCandidate(QString sdp)
{
    auto doc  = QJsonDocument::fromJson(sdp.toUtf8());
    auto obj = doc.object();
    auto ssdp = obj["candidate"].toString();
    std::string sdp_mid,sdps;
    int sdp_mlineindex = 0;

    sdp_mlineindex = obj[kCandidateSdpMlineIndexName].toInt();
    sdp_mid = obj[kCandidateSdpMlineIndexName].toString().toStdString();
    sdps = obj[kCandidateSdpName].toString().toStdString();
    webrtc::SdpParseError error;
    std::unique_ptr<webrtc::IceCandidateInterface> candidate(
        webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, sdps, &error));

    if(nullptr != m_peer_connection_){
        m_peer_connection_->AddIceCandidate(candidate.get());
    }
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " SetRemoteCandidate&&CreateIceCandidate "  + ": " +
                 ssdp).toStdString());
}

void WebrtcHanlder::CreateAnwer()
{
    qDebug()<<"create answer";
    qDebug()<<m_peer_connection_.get();
    m_peer_connection_->CreateAnswer(
        this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " CreateAnswer ").toStdString());
}

webrtc::VideoTrackInterface *WebrtcHanlder::VideoTrack()
{
    return mVideoTrack;
}

void WebrtcHanlder::AddLocalTrack()
{
    if(mAudioTrack == nullptr){
        rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
            m_peer_connection_factory_->CreateAudioTrack(
                kAudioLabel, m_peer_connection_factory_->CreateAudioSource(
                cricket::AudioOptions())));

        auto result_or_error = m_peer_connection_->AddTrack(audio_track, {kStreamId});
        if (!result_or_error.ok()) {
            qDebug() << "Failed to add audio track to PeerConnection: "
                            << result_or_error.error().message();
        }
        mAudioTrack = audio_track.get();
    }else{
        auto result_or_error = m_peer_connection_->AddTrack(mAudioTrack, {kStreamId});
        if (!result_or_error.ok()) {
            qDebug() << "Failed to add audio track to PeerConnection: "
                            << result_or_error.error().message();
        }
    }

    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " m_peer_connection_ AddTrack" + kAudioLabel).toStdString());
    if(mVideoTrack == nullptr){
        rtc::scoped_refptr<CameraCapturer> video_device = new rtc::RefCountedObject<CameraCapturer>();
        if (video_device) {
            video_device->startCapturer();
            rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track_(
                m_peer_connection_factory_->CreateVideoTrack(kVideoLabel, video_device));
            qDebug()<<"local track is "<<video_track_->id().c_str();
            auto result_or_error = m_peer_connection_->AddTrack(video_track_, { kStreamId });
            mVideoTrack = video_track_.get();
            video_track_->AddRef();
            if (!result_or_error.ok()) {
                qDebug() << "Failed to add video track to PeerConnection: "
                    << result_or_error.error().message();
            }
            gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                         " m_peer_connection_ AddTrack" + kVideoLabel).toStdString());
        } else {
            qDebug()<< "OpenVideoCaptureDevice failed";
        }
    }else{
        auto result_or_error = m_peer_connection_->AddTrack(mVideoTrack, { kStreamId });
        if (!result_or_error.ok()) {
            qDebug() << "Failed to add video track to PeerConnection: "
                << result_or_error.error().message();
        }
        gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                     " m_peer_connection_ AddTrack" + kVideoLabel).toStdString());
    }

}

WebrtcHanlder::~WebrtcHanlder()
{

}

void WebrtcHanlder::OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) {

}

void WebrtcHanlder::OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface> > &streams)
{
    qDebug()<<"OnAddTrack"<<receiver->id().c_str();
    if (receiver->track().release()->kind() ==
            webrtc::MediaStreamTrackInterface::kVideoKind)
        OnRemoteTrack(receiver->track().release());

    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " OnAddTrack ").toStdString());
}

void WebrtcHanlder::OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
{
    qDebug()<<"OnRemoveTrack";
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " OnRemoveTrack ").toStdString());
}

void WebrtcHanlder::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> channel) {
    qDebug()<<"OnDataChannel";
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " OnDataChannel ").toStdString());
}

void WebrtcHanlder::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) {
    qDebug()<<"OnIceConnectionChange"<<new_state;
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " OnIceConnectionChange " +
                 IceConnectionStateName(new_state)).toStdString());
    if((new_state ==
            webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionDisconnected)){
        m_peer_connection_->Close();
        OnConectionDisconnected();
    }
    if((new_state ==
            webrtc::PeerConnectionInterface::IceConnectionState::kIceConnectionCompleted)){
        OnConectionComplete();
    }
}

void WebrtcHanlder::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) {
    qDebug()<<"OnIceGatheringChange"<<new_state;
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " OnIceGatheringChange " + IceGatheringStateName(new_state)).toStdString());
}

void WebrtcHanlder::OnIceCandidate(const webrtc::IceCandidateInterface *candidate)
{
    qDebug()<<"on condidate\r\n";

    QJsonObject addr;
    addr.insert(kCandidateSdpMidName, candidate->sdp_mid().c_str());
    addr.insert(kCandidateSdpMlineIndexName,candidate->sdp_mline_index());
    std::string sdp;
    if (!candidate->ToString(&sdp)) {
      RTC_LOG(LS_ERROR) << "Failed to serialize candidate";
      return;
    }
    addr.insert(kCandidateSdpName,sdp.c_str());
    qDebug()<<"condidate:\r\n"<< QString(QJsonDocument(addr).toJson());
    this->mClient->SendICECandidate(mRemoteName,QString(QJsonDocument(addr).toJson()));
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " OnIceCandidate " + QString(QJsonDocument(addr).toJson())).toStdString());
}

void WebrtcHanlder::OnIceConnectionReceivingChange(bool receiving) {
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 " OnIceConnectionReceivingChange " +\
                 QString::asprintf("%d",receiving)).toStdString());
}


const char kSessionDescriptionTypeName[] = "type";
const char kSessionDescriptionSdpName[] = "sdp";
void WebrtcHanlder::OnSuccess(webrtc::SessionDescriptionInterface *desc)
{
    qDebug()<<__FUNCTION__<<desc->type().c_str();
    std::string sdp;
    desc->ToString(&sdp);
    QJsonObject addr;
    addr.insert(kSessionDescriptionTypeName,QString(webrtc::SdpTypeToString(desc->GetType())));
    addr.insert(kSessionDescriptionSdpName,sdp.c_str());
    qDebug()<<"OnSuccess sdp :  "<<QJsonDocument(addr).toJson()<<"  "<<desc->type().c_str();
    // 设置本地sdp
    m_peer_connection_->SetLocalDescription(
          DummySetSessionDescriptionObserver::Create(), desc);
    if(QString(desc->type().c_str()) == "offer"){
        OnOfferSdp(QJsonDocument(addr).toJson());
    }
    if(QString(desc->type().c_str()) == "answer"){
        OnOfferSdp(QJsonDocument(addr).toJson());
    }
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 "PeerConnectionObserver::OnSuccess " + QJsonDocument(addr).toJson()).toStdString());
}

void WebrtcHanlder::OnFailure(webrtc::RTCError error)
{
    qDebug()<<error.message();
    gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__) +
                 "PeerConnectionObserver::OnSuccess " + error.message()).toStdString());
}



void MainWindow::on_pushButton_clicked()
{
    mSignalClient = new SignalClient(QUrl(ui->lineEdit_2->text()),true,this);
    connect(this->mSignalClient,SIGNAL(connected()),this,SLOT(signal_conneted()));
    connect(this->mSignalClient,SIGNAL(response(int ,QJsonObject)),
            this,SLOT( signal_response(int,QJsonObject)));
    mHandler->SetSignalClient(this->mSignalClient);
}

void MainWindow::signal_conneted()
{
    ui->label_5->setText("信令服务器已连接");
    this->mSignalClient->SendLogin();
    ui->label_6->setText(QString("本节点名称:  " + mSignalClient->PeerName()));
}

void MainWindow::on_pushButton_2_clicked()
{
    if(ui->lineEdit->text() != ""){
        if(mSignalClient->Connected()){
            this->mSignalClient->SendInRoom(ui->lineEdit->text());
            this->mSignalClient->SendListRoom(ui->lineEdit->text());
        }
    }
}

void MainWindow::signal_closed()
{
    ui->label_5->setText("信令服务器已断开");
}

void MainWindow::signal_response(int type,QJsonObject data)
{
    qDebug()<<type<<data;
    switch (type) {
    case 2004:  // RESP_LISTROOM
        this->mModel->clear();
        for (auto itr = data.begin();itr != data.end();itr++){
            auto item = new QStandardItem(itr.key());
            item->setEditable(false);
            mModel->appendRow(item);
        }
        break;
    case 2005:  // RESP_SENDSDP
    {
        auto sdp = data["sdp"].toString();
        auto remote_name = data["remote_name"].toString();
        mHandler->SetRemotePeerName(remote_name);

        this->mHandler.get()->SetRemoteSdp(sdp);
        mRemoteName = remote_name;
        if(!mCalling)
            mHandler->CreateAnwer();
        break;
    }
    case 2006: //RESP_SENDCANDIDATE
    {
        auto candidate = data["candidate"].toString();
        auto remote_names = data["remote_name"].toString();
        mHandler->SetRemotePeerName(remote_names);
        mRemoteName = remote_names;
        this->mHandler.get()->SetRemoteCandidate(candidate);
        qDebug()<<"recv candidate"<<candidate;

        break;
    }
    default:
        break;
    }
}

void MainWindow::itemClicked(QModelIndex index)
{
    if(!mSignalClient->Connected()){
        qDebug()<<"请先连接信令服务";
        return;
    }
    this->mLocalVideoTrack = mHandler->VideoTrack();
    qDebug()<<mModel->item(index.row())->text();

    mRemoteName = mModel->item(index.row())->text();
    if(mRemoteName == this->mPeerName){
        return;
    }
    mHandler->CreateOffer();
    mHandler->SetRemotePeerName(mRemoteName);
    mCalling = true;
}

void MainWindow::on_local_sdp(QString sdp)
{
    qDebug()<<"sdp size is "<<sdp.size();
    mSignalClient->SendSDPOffer(mRemoteName,sdp);
}

void MainWindow::on_track_add(webrtc::MediaStreamTrackInterface *data)
{
    qDebug()<<"on_track_add"<<data->kind().c_str();
    mRemoteVideoTrack = reinterpret_cast<webrtc::VideoTrackInterface*>(data);

    if (mRemoteVideoTrack->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) {
        mRemoteVideoTrack = static_cast<webrtc::VideoTrackInterface*>(mRemoteVideoTrack);
        qDebug()<<"remote trackid is "<<mRemoteVideoTrack->id().c_str();
        remote_renderer_.reset(new VideoRenderer( 1, 1, mRemoteVideoTrack));

        connect((VideoRenderer*)(remote_renderer_.get()),
                SIGNAL(UpdateFrame(rtc::scoped_refptr<webrtc::I420BufferInterface>&)),
                (CPlayWidget*)ui->openGLWidget,
                SLOT(OnCameraData(rtc::scoped_refptr<webrtc::I420BufferInterface> &)),
                Qt::ConnectionType::QueuedConnection);
        connect((VideoRenderer*)(remote_renderer_.get()),SIGNAL(NotifySize(uint32_t ,uint32_t )),
               this,SLOT(on_notify_size(uint32_t ,uint32_t)),
                Qt::ConnectionType::QueuedConnection);

        gLog()->Log((QString::asprintf("%s %d",__FILE__,__LINE__)   +
                     " on_track_add ").toStdString());
    }
}

void MainWindow::on_notify_size(uint32_t width, uint32_t height)
{
    ui->openGLWidget->SetImgSize(width,height);
    ui->openGLWidget->SetDataType(CPlayWidget::IMG_TYPE::TYPE_I420);
}

VideoRenderer::VideoRenderer(int width, int height, webrtc::VideoTrackInterface *track_to_render)
: rendered_track_(track_to_render)
{
    ::InitializeCriticalSection(&buffer_lock_);
    ZeroMemory(&bmi_, sizeof(bmi_));
    bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi_.bmiHeader.biPlanes = 1;
    bmi_.bmiHeader.biBitCount = 32;
    bmi_.bmiHeader.biCompression = BI_RGB;
    bmi_.bmiHeader.biWidth = width;
    bmi_.bmiHeader.biHeight = -height;
    bmi_.bmiHeader.biSizeImage =
        width * height * (bmi_.bmiHeader.biBitCount >> 3);
    rendered_track_->AddOrUpdateSink(this, rtc::VideoSinkWants());
}

VideoRenderer::~VideoRenderer()
{
    rendered_track_->RemoveSink(this);
    ::DeleteCriticalSection(&buffer_lock_);
}

static void RawToBmp(unsigned char *pRawImage, int ImageHeight, int ImageWidth, int bitcount,std::string filePath)
{

    unsigned char *imgData;
    LONGLONG dataSizePerLine = ((ImageWidth * bitcount + 31) >> 5) << 2;


    int plaLen = bitcount <= 8 ? 2 << (bitcount - 1) : 0;
    std::cout << "plaLen = " << plaLen << endl;
    int headerLength = 14 + 40 + plaLen * 4;
    LONGLONG dataLength = dataSizePerLine*(ImageHeight - 1) + ImageWidth*bitcount / 8;
    std::cout << "headerLength = " << headerLength << endl;
    std::cout << "dataLength = " << dataLength << endl;
    short int biPlanes = 1;
    char bm[2] = { 'B', 'M' };
    long bfReserved1 = 0;
    LONGLONG bfSize = headerLength + dataLength;
    long biHeight = ImageHeight*(-1);
    long bfOffBits = headerLength;
    long bisize = 40;
    long biCompression = 0; LONGLONG biSizeImage = dataLength;
    long biXPelsPerMeter = 0, biYPelsPerMeter = 0;
    long biClrUsed = plaLen; int biClrImportant = 0;
    imgData = new unsigned char[headerLength + dataLength];
    memset(imgData, 0, headerLength + dataLength);
    memcpy(imgData, &bm, 2);
    memcpy(imgData + 2, &bfSize, 4);
    memcpy(imgData + 6, &bfReserved1, 4);
    memcpy(imgData + 10, &bfOffBits, 4);
    memcpy(imgData + 14, &bisize, 4);
    memcpy(imgData + 18, &ImageWidth, 4);
    memcpy(imgData + 22, &biHeight, 4);
    memcpy(imgData + 26, &biPlanes, 2);
    memcpy(imgData + 28, &bitcount, 2);
    memcpy(imgData + 30, &biCompression, 4);
    memcpy(imgData + 34, &biSizeImage, 4);
    memcpy(imgData + 38, &biXPelsPerMeter, 4);
    memcpy(imgData + 42, &biYPelsPerMeter, 4);
    memcpy(imgData + 46, &biClrUsed, 4);
    memcpy(imgData + 50, &biCompression, 4);

    if (headerLength > 54) {
        if (bitcount == 1) {
            for (char i = 0; i < 2; i++) {
                char gray[4] = { char(i * 255), char(i * 255), char(i * 255), char(255) };
                memcpy(imgData + 54 + 4 * i, gray, 4);
            }
        }
        else if (bitcount == 4) {
            for (char i = 0; i < 16; i++) {
                char gray[4] = { char(i * 17), char(i * 17), char(i * 17), char(255) };
                memcpy(imgData + 54 + 4 * i, gray, 4);
            }
        }
        else  if (bitcount == 8) {
            for (int i = 0; i < 255; i++) {
                char gray[4] = { char(i), char(i), char(i), char(255)};
                memcpy(imgData + 54 + 4 * i, gray, 4);
            }
        }
    }


    int dw = ImageWidth*bitcount / 8;
    for (int i = 0; i < ImageHeight; i++)
    {
        memcpy(imgData + headerLength + dataSizePerLine*i, pRawImage + dw*i, dw);
    }



    FILE *fp_bmp;
    fp_bmp = fopen(filePath.c_str()/*"temp.bmp"*/, "wb");
    fwrite((void*)imgData, bfSize, 1, fp_bmp);
    fclose(fp_bmp);


}

void VideoRenderer::OnFrame(const webrtc::VideoFrame &video_frame)
{
    {
        static bool first = true;
        AutoLock<VideoRenderer> lock(this);
        rtc::scoped_refptr<webrtc::I420BufferInterface> buffer(
            video_frame.video_frame_buffer()->ToI420());
        if (video_frame.rotation() != webrtc::kVideoRotation_0) {
            buffer = webrtc::I420Buffer::Rotate(*buffer, video_frame.rotation());
        }
        RTC_DCHECK(image_ != NULL);
        auto i420_buffer_ = video_frame.video_frame_buffer()->ToI420();
        auto type = video_frame.video_frame_buffer()->type();
        SetSize(i420_buffer_->width(), i420_buffer_->height());
        if(first){
            NotifySize(i420_buffer_->width(),
                       i420_buffer_->height());
            first = false;
        }
        qDebug()<<"onframe "<< i420_buffer_->width()
               << i420_buffer_->height();
        UpdateFrame(buffer);
    }
}

void VideoRenderer::SetSize(int width, int height)
{
    if (width == bmi_.bmiHeader.biWidth && height == bmi_.bmiHeader.biHeight) {
      return;
    }

    bmi_.bmiHeader.biWidth = width;
    bmi_.bmiHeader.biHeight = height;
    bmi_.bmiHeader.biSizeImage =
        width * height * (bmi_.bmiHeader.biBitCount >> 3);
           image_ = new uint8_t[bmi_.bmiHeader.biSizeImage];
}

void MainWindow::on_pushButton_3_clicked()
{
    if(mRemoteVideoTrack != nullptr){
        mRemoteVideoTrack->set_enabled(false);
    }

}

void MainWindow::on_pushButton_4_clicked()
{
    if(mLocalVideoTrack != nullptr){
        mLocalVideoTrack->set_enabled(false);
    }
}

void MainWindow::on_pushButton_5_clicked()
{
    if(mRemoteVideoTrack != nullptr){
        mRemoteVideoTrack->set_enabled(false);
    }
}

void MainWindow::on_pushButton_6_clicked()
{
    if(mLocalVideoTrack != nullptr){
        mLocalVideoTrack->set_enabled(true);
    }
}
